/****************************************************************************
 *  Copyright: National ICT Australia,  2007 - 2011                         *
 *  Developed at the ATP lab, Networked Systems research theme              *
 *  Author(s): Athanassios Boulis, Yuriy Tselishchev                        *
 *  This file is distributed under the terms in the attached LICENSE file.  *
 *  If you do not find this file, copies can be found by writing to:        *
 *                                                                          *
 *      NICTA, Locked Bag 9013, Alexandria, NSW 1435, Australia             *
 *      Attention:  License Inquiry.                                        *
 *                                                                          *
 ****************************************************************************/

#include "MacRLApp.h"

Define_Module(MacRLApp);

void MacRLApp::startup()
{
	isSink = par("isSink");
	recipientAddress = par("nextRecipient").stringValue();
	
	startupDelay = par("startupDelay");
	packet_rate = par("packet_rate") ;
	randomSend = par("randomSend");

//	int id = atoi(SELF_NETWORK_ADDRESS);
/*	if ((id % 2) == 0)
	packet_rate = par("packet_rate") ;
	else packet_rate = 2;
*/

	trace() << "START MacRLApp test - Node location: " << mobilityModule->getLocation().x << ", " << mobilityModule->getLocation().y;
		
	packet_spacing = packet_rate > 0 ? 1 / float (packet_rate) : -1;
	dataSN = 0;
	srand(time(NULL));

	if (packet_spacing > 0 && recipientAddress.compare(SELF_NETWORK_ADDRESS) != 0)
		setTimer(SCHEDULE_PACKET, startupDelay);
	else
		trace() << "Not sending packets";
		//~ setTimer(START_SYN, 0.2);

	declareOutput("Packets received per node");
}

void MacRLApp::fromNetworkLayer(ApplicationPacket * rcvPacket,
		const char *source, double rssi, double lqi)
{
	int sequenceNumber = rcvPacket->getSequenceNumber();

	if (recipientAddress.compare(SELF_NETWORK_ADDRESS) == 0) {
		trace() << "Received packet #" << sequenceNumber << " from node " << source;
		collectOutput("Packets received per node", atoi(source));
	// Packet has to be forwarded to the next hop recipient
	} else {
		ApplicationPacket* fwdPacket = rcvPacket->dup();
		// Reset the size of the packet, otherwise the app overhead will keep adding on
		fwdPacket->setByteLength(0);
		toNetworkLayer(fwdPacket, recipientAddress.c_str());
	}
}

void MacRLApp::timerFiredCallback(int index)
{
	switch (index) {
		
		case SCHEDULE_PACKET:{
			setTimer(SCHEDULE_PACKET, packet_spacing);			
			if(randomSend){
				double r= ((double)rand()*(double)packet_spacing) / (double)RAND_MAX;
				//~ trace() << "Random: " << r;
				setTimer(SEND_PACKET, r);
				break;
			}
			//~ else{
				//~ trace() << "else ...";
				//~ setTimer(SEND_PACKET, packet_spacing-0.02);
			//~ }
		}
		
		case SEND_PACKET:{
			trace() << "Sending packet #" << dataSN;
			//~ toNetworkLayer(createGenericDataPacket(0, dataSN), par("nextRecipient"));
			toNetworkLayer(createGenericDataPacket(0, dataSN), "SINK");
			dataSN++;
			break;
		}
		
		//~ case START_SYN:{
			//~ trace() << "Sending SYN";
			//~ toNetworkLayer(createGenericDataPacket(0, dataSN), BROADCAST_NETWORK_ADDRESS);
			//~ break;
		//~ }
	}
}

// This method processes a received carrier sense interupt. Used only for demo purposes
// in some simulations. Feel free to comment out the trace command.
void MacRLApp::handleRadioControlMessage(RadioControlMessage *radioMsg)
{
	switch (radioMsg->getRadioControlMessageKind()) {
		case CARRIER_SENSE_INTERRUPT:
			trace() << "CS Interrupt received! current RSSI value is: " << radioModule->readRSSI();
                        break;
	}
}

